﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BatallaNavalgo
{
    public class Tablero
    {
        private Casilla[,] casillas;
        private List<Nave> naves;

        /****************************************************/

        public Tablero()
        {
            naves = new List<Nave>();
            casillas = new Casilla[10, 10];
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    int[] posicion = new int[2];
                    posicion[0] = i;
                    posicion[1] = j;
                    casillas[i, j] = new Casilla(posicion);
                }
            }
            Random random = new Random();
            for(int i = 0; i<2; i++)
                if(random.Next(0,2) == 0)
                    this.naves.Add(new Lancha(new int[2] { random.Next(0, 9), random.Next(0, 10) }, new int[2] { random.Next(-1, 2), random.Next(-1, 2) }, 0, this));
                else this.naves.Add(new Lancha(new int[2] { random.Next(0, 10), random.Next(0, 9) }, new int[2] { random.Next(-1, 2), random.Next(-1, 2) }, 1, this)); 
            for (int i = 0; i < 2; i++)
                if(random.Next(0,2) == 0)
                    this.naves.Add(new Destructor(new int[2] { random.Next(0, 8), random.Next(0, 10) }, new int[2] { random.Next(-1, 2), random.Next(-1, 2) }, 0, this));
                else this.naves.Add(new Destructor(new int[2] { random.Next(0, 10), random.Next(0, 8) }, new int[2] { random.Next(-1, 2), random.Next(-1, 2) }, 1, this));
            if (random.Next(0, 2) == 0)
                this.naves.Add(new Buque(new int[2] { random.Next(0, 7), random.Next(0, 10) }, new int[2] { random.Next(-1, 2), random.Next(-1, 2) }, 0, this));
            else this.naves.Add(new Buque(new int[2] { random.Next(0, 10), random.Next(0, 7) }, new int[2] { random.Next(-1, 2), random.Next(-1, 2) }, 1, this));
            if (random.Next(0, 2) == 0)
                this.naves.Add(new PortaAviones(new int[2] { random.Next(0, 6), random.Next(0, 10) }, new int[2] { random.Next(-1, 2), random.Next(-1, 2) }, 0, this));
            else this.naves.Add(new PortaAviones(new int[2] { random.Next(0, 10), random.Next(0, 6) }, new int[2] { random.Next(-1, 2), random.Next(-1, 2) }, 1, this));
            if (random.Next(0, 2) == 0)
                this.naves.Add(new RompeHielos(new int[2] { random.Next(0, 8), random.Next(0, 10) }, new int[2] { random.Next(-1, 2), random.Next(-1, 2) }, 0, this));
            else this.naves.Add(new RompeHielos(new int[2] { random.Next(0, 10), random.Next(0, 8) }, new int[2] { random.Next(-1, 2), random.Next(-1, 2) }, 1, this));    
        }


        /**************************************************/

        public void CargarNave(Nave nave)
        {
            this.naves.Add(nave);

        }

        /***************************************************/

        public Casilla GetCasilla(Tuple<int, int> posicion)
        {
            if (posicion.Item1 < 0 | posicion.Item1 > 9 | posicion.Item2 < 0 | posicion.Item2 > 9)
                throw new PosicionIncorrectaException();
            return this.casillas[posicion.Item1, posicion.Item2];
        }

        /***************************************************/

        public List<Nave> Naves
        {
            get{return this.naves;}
        }

        /**************************************************/


        public void RealizarImpactos()
        {
            List<Nave> lista = new List<Nave>();
            for (int i = 0; i < this.naves.Count; i++)
            {
                this.naves[i].ChequearImpactos();
                if (this.naves[i].EstaDestruida())
                    lista.Add(this.naves[i]);
            }
            foreach (Nave nave in lista)
                this.naves.Remove(nave);
            for (int i = 0; i < 10; i++)
                for (int j = 0; j < 10; j++)
                    this.casillas[i, j].PasarTurno();
        }

        


        /***************************************************/

        public void ColocarDisparo(Disparo disparo, Tuple<int, int> posicion)
        {
            try
            {
                this.GetCasilla(posicion).AlmacenarDisparo(disparo);
            }
            catch (PosicionIncorrectaException)
            {
            }
        }

        /***************************************************/

        public void PasarTurno()
        {
            for (int i = 0; i < this.naves.Count; i++)
                this.naves[i].Mover();
        }
        
        /***************************************************/



        public FragmentoDeNave GetFragmentoDeNave(int[] posicion)
        {
            FragmentoDeNave fragmento = null;
            foreach (Nave nave in this.naves)
            {

                FragmentoDeNave fragmentoActual = nave.GetFragmentoDeNave(posicion);
                if (fragmentoActual != null)
                    if (fragmento == null)
                        fragmento = fragmentoActual;
                    else if (fragmento.EstaDestruido())
                        fragmento = fragmentoActual;
            }
            return fragmento;
        }

        public bool EstaVacio()
        {
            if (this.naves.Count == 0)
                return true;
            return false;
        }
    }
}
